package models;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import views.DesktopView;
import views.SurveyResultsView;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import controllers.DesktopController;



import main.ConsoleInterpreterSingleton;
import mvc.AbstractModel;
import mvc.AbstractView;

public class DesktopModel extends AbstractModel
{
	
	public DesktopModel(String name, String caption)
	{
		super(name, caption);
	}

	public void createSurvey(String filename)
	{	
		AbstractModel survey = new SurveyModel(filename, "[SURVEY VIEW]");
		SurveyModel.save(survey);
		// tell the user this survey has been created
		this.setCaption("Created survey " + filename);
		this.notifyObservers();
	}
	
	public void editSurvey(String filename)
	{
		AbstractModel survey = loadSurvey(filename);
		if(survey == null)
		{
			return;
		}
		initSurvey(survey);
	}
	
	public void viewResults(String resultsFilename)
	{
		SurveyResultsModel results = loadResults(resultsFilename);
		if(results == null)
		{
			return;
		}
		results.createView();
		results.notifyObservers();
	}
	
	public void gradeSurvey(String resultsFilename)
	{
		SurveyResultsModel results = loadResults(resultsFilename);
		if(results == null)
		{
			return;
		}
		initSurveyResults(results);
		results.gradeSurvey();
	}
	
	public void takeSurvey(String firstName, String lastName, String surveyFilename, String resultFilename)
	{
		SurveyResultsModel results = new SurveyResultsModel(firstName, lastName, surveyFilename, resultFilename);
		SurveyModel survey = loadSurvey(surveyFilename);
		if(survey == null)
		{
			return;
		}
		initSurvey(survey);
		survey.take(results);
	}
	
	
	@Override
	public AbstractView createView()
	{
		DesktopController controller = new DesktopController(this);
		AbstractView view  = new DesktopView(controller, this);
		this.attach(view);
		return view;
	}

	private SurveyModel loadSurvey(String filename)
	{
		// check if file exists
		File xmlFile = new File(filename);
		boolean fileExists = xmlFile.exists();
		if(!fileExists)
		{
			setCaption("file " + filename + " does not exist, please try again!\n");
			notifyObservers();
			return null;
		}
		// load a SurveyModel from an xml file
		FileInputStream in = null;
		try
		{
			in = new FileInputStream(filename);
			SurveyModel survey = (SurveyModel)xstream.fromXML(in);
			survey.setControllerMonitorView((AbstractView)itsIObservers.get(0));
			return survey;
		} 
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}	
		return null;
	}
	
	private SurveyResultsModel loadResults(String resultsFilename)
	{
		// check if file exists
		File xmlFile = new File(resultsFilename);
		boolean fileExists = xmlFile.exists();
		if(!fileExists)
		{
			setCaption("file " + resultsFilename + " does not exist, please try again!\n");
			notifyObservers();
			return null;
		}
		// load from an xml file
		FileInputStream in = null;
		try
		{
			in = new FileInputStream(resultsFilename);
			SurveyResultsModel results = (SurveyResultsModel)xstream.fromXML(in);
			results.setControllerMonitorView((AbstractView)itsIObservers.get(0));
			return results;
		} 
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}	
		return null;
	}
	
	private void initSurvey(AbstractModel survey)
	{
		AbstractView surveyView = survey.createView();
		survey.setCaption("[Survey View]");
		survey.notifyObservers();
		ConsoleInterpreterSingleton interpreter = ConsoleInterpreterSingleton.getInstance();
		interpreter.pipeEventsTo(surveyView);
	}
	
	private void initSurveyResults(SurveyResultsModel results)
	{
		setCaption("[Survey Results Grading View], here are the results:");
		notifyObservers();
		AbstractView resultsView = results.createView();
		ConsoleInterpreterSingleton interpreter = ConsoleInterpreterSingleton.getInstance();
		interpreter.pipeEventsTo(resultsView);
	}
	
	XStream xstream = new XStream(new DomDriver());
}
